package com.kyd.push.push;

import cn.jpush.api.JPushClient;
import cn.jpush.api.push.PushResult;
import cn.jpush.api.push.model.Message;
import cn.jpush.api.push.model.Options;
import cn.jpush.api.push.model.Platform;
import cn.jpush.api.push.model.PushPayload;
import cn.jpush.api.push.model.audience.Audience;
import cn.jpush.api.push.model.notification.AndroidNotification;
import cn.jpush.api.push.model.notification.IosNotification;
import cn.jpush.api.push.model.notification.Notification;

import com.kyd.push.common.utils.JsonKit;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.Set;

/**
 * JPushKit
 *
 * @author kejw on 2018/9/28
 */
@Slf4j
public class JPushKit {

	private static String appKey;
	private static String masterSecret;

	public static JPushKit newInstance(String appKey, String masterSecret) {
		return new JPushKit(appKey, masterSecret);
	}

	public JPushKit() {}

	public JPushKit(String appKey, String masterSecret) {
		this.appKey = appKey;
		this.masterSecret = masterSecret;
	}

	/**
	 * 设置设备的别名与标签
	 *
	 * @param registrationId
	 * @param alias
	 */
	public void updateDeviceTagAlias(String registrationId, String alias) {
		updateDeviceTagAlias(registrationId, alias, null);
	}

	/**
	 * 设置设备的别名与标签
	 *
	 * @param registrationId
	 * @param alias
	 * @param tagsToAdd
	 */
	public void updateDeviceTagAlias(String registrationId, String alias, Set<String> tagsToAdd) {
		JPushClient jpushClient = new JPushClient(masterSecret, appKey);
		try {
			jpushClient.updateDeviceTagAlias(registrationId, alias, tagsToAdd, null);
			log.info("[JPush]设置设备的别名与标签, registrationId={} alias={}", registrationId, alias);
		} catch (Exception e) {
			log.error("[JPush]设置设备的别名与标签失败, registrationId={} alias={} errorMsg={}", registrationId, alias, e.getMessage());
		}
	}

	/**
	 * 消息推送
	 *
	 * @param request 推送请求消息对象
	 * @param registrationId 推送设备的registrationId
	 */
	public void sendPush(PushRequest request, String... registrationId) {
//		if (StringUtils.isBlank(request.getNotification()) && StringUtils.isBlank(request.getMessage())) {
//			throw new IllegalArgumentException("notification or message should be set at least one.");
//		}


		PushPayload.Builder builder = PushPayload.newBuilder()
				.setPlatform(Platform.all())
				.setAudience(Audience.registrationId(registrationId))
				.setOptions(Options.newBuilder().setApnsProduction(false).build()) // APNs 的推送环境是“生产”（如果不显式设置的话，Library 会默认指定为开发）
				;

		// 通知
		if (StringUtils.isNotBlank(request.getNotification())) {
//			if (request.getExtras().get("type") == null) {
//				throw new IllegalArgumentException("notification extras type can not null.");
//			}
//			if (request.getExtras().get("data") == null) {
//				throw new IllegalArgumentException("notification extras data can not null.");
//			}

			Notification notification = Notification.newBuilder()
					.addPlatformNotification(AndroidNotification.newBuilder()
							.setAlert(request.getNotification())
							.addExtras(request.getExtras())
							.build())
					.addPlatformNotification(IosNotification.newBuilder()
							.setAlert(request.getNotification())
							.addExtras(request.getExtras())
							.setSound("broadcast.mp3")
							.setContentAvailable(true)
							.setMutableContent(true)
							.setBadge(1)
							.build())
					.build();

			builder.setNotification(notification);
		}

		// 自定义消息
		if (StringUtils.isNotBlank(request.getMessage())) {
			builder.setMessage(Message.content(request.getMessage()));
		}

		PushPayload payload = builder.build();

		try {
			JPushClient jpushClient = new JPushClient(masterSecret, appKey);
			PushResult result = jpushClient.sendPush(payload);
			log.info("[JPush]推送结果: {}, 推送通知: {}, 通知扩展: {}, 自定义消息: {}", result.toString(), request.getNotification(), JsonKit.INSTANCE.toJson(request.getExtras()), request.getMessage());
		} catch (Exception e) {
			log.error("[JPush]推送失败, notification={} registrationId={} errorMsg={}", request.getNotification(), String.join(",", registrationId), e.getMessage());
		}
	}


	/**
	 * 消息推送
	 *
	 * @param request 推送请求消息对象
	 * @param alias 推送设备的别名
	 */
	public static void sendPushByAlias(PushRequest request, String... alias) {
		if (alias.length == 0) {
			throw new IllegalArgumentException("请至少设置一个alias");
		}
		if (request.getNotification() == null && request.getMessage() == null) {
			throw new IllegalArgumentException("notification or message should be set at least one.");
		}

		PushPayload.Builder builder = PushPayload.newBuilder()
				.setPlatform(Platform.all())
				.setAudience(Audience.alias(alias))
				.setOptions(Options.newBuilder().setApnsProduction(false).build()) // APNs 的推送环境是“生产”（如果不显式设置的话，Library 会默认指定为开发）
				;

		// 通知
		if (request.getNotification() != null) {
			if (request.getExtras().get("type") == null) {
				throw new IllegalArgumentException("notification extras type can not null.");
			}
			if (request.getExtras().get("data") == null) {
				throw new IllegalArgumentException("notification extras data can not null.");
			}

			Notification notification = Notification.newBuilder()
					.addPlatformNotification(AndroidNotification.newBuilder()
							.setAlert(request.getNotification())
							.addExtras(request.getExtras())
							.build())
					.addPlatformNotification(IosNotification.newBuilder()
							.setAlert(request.getNotification())
							.addExtras(request.getExtras())
							.setSound("broadcast.mp3")
							.setContentAvailable(true)
							.setMutableContent(true)
							.setBadge(1)
							.build())
					.build();

			builder.setNotification(notification);
		}

		// 自定义消息
		if (request.getMessage() != null) {
			builder.setMessage(Message.content(request.getMessage()));
		}

		PushPayload payload = builder.build();

		try {
			JPushClient jpushClient = new JPushClient(masterSecret, appKey);
			PushResult result = jpushClient.sendPush(payload);
//			log.info("[JPush]推送结果: {} \n--->推送通知: {} \n--->通知扩展: {} \n--->自定义消息: {}", result.toString(), request.getNotification(), request.extrasJson(), request.msgJson());
		} catch (Exception e) {
			log.error("[JPush]推送失败, notification={} alias={} errorMsg={}", request.getNotification(), String.join(",", alias), e.getMessage());
		}
	}
}
